home *** CD-ROM | disk | FTP | other *** search
-
- /* VirusX - by Steve Tibbett
-
- The complete Virus Elimination System!
-
- Please - if you find a new virus, Send me a copy!
- (And warn me it's on the disk!). I want to keep
- this program current. (Feel free to put something
- neat (but not copyrighted) on the disk also!)
- */
-
- /* History:
-
- A few weeks ago: V1.0 written.
- A few days later: V1.01 released - V1.0 wrote garbage when disk was Write Prot.
- 27-Mar-88: V1.2 - Added Byte Bandit RAM detection, and disk detection.
- (Actually, it's well after Midnight - make that 28-Mar-88)
- Just after
- uploading V1.2
- to Amic BBS: Realized I put the wrong version in the ARC file - Had to
- rename V1.2 to V1.21...
-
- */
-
- /* - Ok, it's not the cleanest code in the world - it was written in two
- days, for a specific purpose, and it works! */
-
- struct Port *diskport; /* disk's port.*/
- struct IOStdReq *diskreq; /* disk's IOStdReq */
-
- int DisksChecked, DisksInstalled, SCAFound; /* for title bar info */
-
- char titlebuffer[80];
-
- /* Who needs includes with Aztec? Everything's precompiled! */
- #include <devices/bootblock.h>
- /* Ok, ONE include... */
-
- /* Amount of boot code we've got (approx): */
- #define BSIZE 40
-
- int ChangeCount[4]; /* TD_CHANGECOUNT for all 4 drives */
-
- int LastSum; /* Used in the checksumming */
-
- int CheckDrives; /* Boolean, from the command line */
-
- int error; /* sort of a temporary variable sort of */
-
- unsigned char diskbuffer[3*512];/* Everything ends up in here.
- I suppose I should have AllocMem'ed this,
- but it's SO easy this way */
-
- /* Warning messages. These messages get modified before being displayed
- (Unless you DO have a DF9:) */
- char TEXTPTR[] = "Danger: The disk in DF9: is";
- char NBCTEXT[] = "Danger: The disk in DF9: has"; /* What a waste, eh? */
- char CopyText[40];
-
- /* This is a byte by byte copy of working boot block code. Check it
- out if you like. This is what gets written back to the disk when you
- ask VirusX to fix a disk. */
-
- unsigned char bootblock[] = { 'D', 'O', 'S', 0, 0xc0, 0x20, 0x0f, 0x19,
- 0, 0, 3, 0x70, 0x43, 0xfa, 0, 0x18,
- 0x4e, 0xae, 0xff, 0xa0, 0x4a, 0x80, 0x67, 0x0a, 0x20, 0x40, 0x20, 0x68,
- 0x00, 0x16, 0x70, 0x00, 0x4e, 0x75, 0x70, 0xff, 0x60, 0xfa, 0x64,
- 0x6f, 0x73, 0x2e, 0x6c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79,0,0,0,0,0};
-
- /* for IntuiText's */
- char def_font[] ="topaz.font";
-
- struct TextAttr TxtAt_Plain = { (UBYTE *)def_font, 8,
- FS_NORMAL, FPF_ROMFONT};
-
- /*** Non SCA warning requester IntuiText's ***/
- struct IntuiText Body2 = {
- 0, 1, JAM2, 20,18, &TxtAt_Plain,(UBYTE *)"Nonstandard Boot Code!", NULL };
- struct IntuiText Body1 = {
- 0, 1, JAM2, 20, 8, &TxtAt_Plain, (UBYTE *)NBCTEXT, &Body2 };
- struct IntuiText Pos = {
- 0, 1, JAM2, 7,3, &TxtAt_Plain, "Remove it", NULL };
- struct IntuiText Neg = {
- 0, 1, JAM2, 7,3, &TxtAt_Plain, "Ignore it", NULL };
-
- /***** SCA Danger Requester IntuiText's ******/
- struct IntuiText SCABody2 = {
- 0, 1, JAM2, 20,18, &TxtAt_Plain,(UBYTE *) "infected with an SCA Virus!!", NULL };
- struct IntuiText SCABody = {
- 0, 1, JAM2, 20, 8, &TxtAt_Plain, (UBYTE *)TEXTPTR, &SCABody2 };
- struct IntuiText SCAPos = {
- 0, 1, JAM2, 7,3, &TxtAt_Plain, "Remove it", NULL };
- struct IntuiText SCANeg = {
- 0, 1, JAM2, 7,3, &TxtAt_Plain, "Ignore it", NULL };
-
- /***** BBANDIT Requester IntuiText's ******/
- struct IntuiText BBDiskbody3 = {
- 0, 1, JAM2, 20,30, &TxtAt_Plain, CopyText, NULL };
- struct IntuiText BBDiskbody2 = {
- 0, 1, JAM2, 20,18, &TxtAt_Plain,(UBYTE *) "infected with the Byte Bandit VIRUS!", &BBDiskbody3};
- struct IntuiText BBDiskbody = {
- 0, 1, JAM2, 20, 8, &TxtAt_Plain, (UBYTE *)TEXTPTR, &BBDiskbody2 };
-
- /***** BBandit Notice - Removed from Memory ****/
- struct IntuiText BBMem3 = {
- 0, 1, JAM2, 20,8, &TxtAt_Plain,(UBYTE *) "NOTICE: The Byte Bandit VIRUS was found", NULL };
- struct IntuiText BBMem2 = {
- 0, 1, JAM2, 20,18, &TxtAt_Plain,(UBYTE *) "in memory, and is now disabled. See the", &BBMem3 };
- struct IntuiText BBMem1 = {
- 0, 1, JAM2, 20,28, &TxtAt_Plain,(UBYTE *) "documentation for more information!", &BBMem2 };
- struct IntuiText BBMPos = {
- 0, 1, JAM2, 7,3, &TxtAt_Plain, " Thanks! ", NULL };
- struct IntuiText BBMNeg = {
- 0, 1, JAM2, 7,3, &TxtAt_Plain, " Thanks! ", NULL };
-
-
- /***** Write Protect Error Requester IntuiText's ******/
- struct IntuiText ERRBody2 = {
- 0, 1, JAM2, 20,18, &TxtAt_Plain,(UBYTE *) "Write Protected.", NULL };
- struct IntuiText ERRBody = {
- 0, 1, JAM2, 20, 8, &TxtAt_Plain, (UBYTE *)"DISK ERROR: Disk is", &ERRBody2 };
- struct IntuiText ERRPos = {
- 0, 1, JAM2, 7,3, &TxtAt_Plain, "Retry", NULL };
- struct IntuiText ERRNeg = {
- 0, 1, JAM2, 7,3, &TxtAt_Plain, "Cancel", NULL };
-
- /***** Rewrite block? Really? ******/
- struct IntuiText REWBody3 = {
- 0, 1, JAM2, 20,28, &TxtAt_Plain,(UBYTE *) "boot sectors?", NULL };
- struct IntuiText REWBody2 = {
- 0, 1, JAM2, 20,18, &TxtAt_Plain,(UBYTE *) "rewrite that disk's boot", &REWBody3};
- struct IntuiText REWBody = {
- 0, 1, JAM2, 20, 8, &TxtAt_Plain, (UBYTE *)"Are you sure you want to", &REWBody2 };
- struct IntuiText REWPos = {
- 0, 1, JAM2, 7,3, &TxtAt_Plain, "Yes", NULL };
- struct IntuiText REWNeg = {
- 0, 1, JAM2, 7,3, &TxtAt_Plain, "No!", NULL };
-
- struct IntuitionBase *IntuitionBase;
- struct GfxBase *GfxBase;
- struct Window *LittleWindow;
- struct IntuiMessage *Message;
- struct RastPort *RP;
-
- int Keepgoing; /* a boolean flag. it's false when we want out. */
- int x, y, i; /* left over from my using Basic */
-
- /*** The Newwindow Structure. ***/
-
- char TITLETEXT[] = "VirusX 1.21 by Steve Tibbett";
- struct NewWindow NewLittleWindow = {
- 128, /* Left, Top, Width, Height */
- 0,
- 309,
- 10,
- 0, /* Frontpen, Backpen */
- 1,
- DISKINSERTED | CLOSEWINDOW | VANILLAKEY | MOUSEBUTTONS, /* IDCMP Flagz */
- WINDOWDRAG | WINDOWDEPTH | RMBTRAP | WINDOWCLOSE | NOCAREREFRESH, /* Windo Flagz */
- NULL,
- NULL,
- TITLETEXT, /* My name. Dont touch it!! */
- NULL,
- NULL,
- 0,
- 0,
- 0,
- 0,
- WBENCHSCREEN,
- };
-
- /*********************Da Beginnin*************************/
- main(argc, argv)
- int argc;
- char *argv[];
- {
- int OldPri;
-
-
- /* Come on, folks, is intuition never NOT going to be available???? */
- IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",0);
-
- /* Same with GfxBase. If GfxBase is gone, we DESERVE to crash. */
- GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",0);
-
-
- /* If checkdrives is true, later on it means we want to check all the drives
- with disks in them for viruses. */
-
- CheckDrives = TRUE;
-
-
- /* Save OldPri so we can restore it later on. We're so nice. */
- OldPri = SetTaskPri(FindTask(0), 19); /* and stick us up high. */
- diskport = CreatePort(0,0);
- diskreq = CreateStdIO(diskport);
-
- SetUp();
-
- CheckMemoryForViruses(); /* New to 1.2 - Check is Byte Bandit in RAM? */
-
- DoLittle(); /* The main loop. Do Little. Ya. */
-
- /* restore priorities to saneness, and take off, eh? */
- SetTaskPri(FindTask(0), OldPri);
-
- DeletePort(diskport);
- DeleteStdIO(diskreq);
-
- exit(FALSE);
- }
-
- /*********************/
- DoLittle()
- {
- register int Code;
- register int Class; /* gee */
- register int KG2; /* KeepGoing 2. Another booleean. */
-
- LittleWindow = OpenWindow(&NewLittleWindow);
- if (LittleWindow == NULL) exit(400L); /* No memory to open little window! */
-
- KG2 = TRUE;
- RP = LittleWindow->RPort; /* easier than typing Move(LittleWindow->RP... all
- the time */
- if (CheckDrives == TRUE) /* Check all drives upon execution (fool */
- { /* ChangeCount to 1000) */
- for (x = 0; x < 4; x++) ChangeCount[x] = 1000;
- CheckBlock(); /* CheckBlock() checks boot block for virus. */
- CheckDrives = FALSE; /* so we don't do it again */
- };
-
- SetAPen(RP, 1);
- SetBPen(RP, 0);
- SetDrMd(RP, JAM2); /* ya. JAM 2! Love that name! */
-
- while (KG2 == TRUE)
- {
- sprintf(titlebuffer, "VirusX: Disks Checked: %d Disks Installed: %d Viruses Found: %d", DisksChecked, DisksInstalled, SCAFound);
- SetWindowTitles(LittleWindow, -1, titlebuffer);
- Message = GetMsg(LittleWindow->UserPort);
- while (Message == NULL)
- {
- /* Lets be nice to other tasks! Ya! */
- Wait(1<<LittleWindow->UserPort->mp_SigBit);
- Message = GetMsg(LittleWindow->UserPort);
- };
- Class = Message->Class;
- Code = Message->Code;
- if (Message != NULL) ReplyMsg(Message);
-
- if (Class == CLOSEWINDOW)
- {
- CloseWindow(LittleWindow);
- exit(FALSE);
- };
-
- if (Class == DISKINSERTED) CheckBlock();
- };
-
- /* KG2 = false, we fell thru to here. Ow. */
-
- CloseWindow(LittleWindow);
- return;
- }
-
- /**********************/
- puts(str) /* outputs a string, but is REAL small. */
- char *str[];
- {
- Write(Output(), str, strlen(str));
- }
-
- /********************/
- /* Opens trackdisk, finds out who's out there, and sets Changecount up accordioningly. */
- /********************/
-
- SetUp()
- {
-
- for (x = 0; x < 4; x++) /* go thru all 4 possible drives */
- {
- ChangeCount[x] = 0;
- error = OpenDevice("trackdisk.device",x,diskreq,0);
- if (error > 0) continue; /* no drive here */
- diskreq->io_Command = TD_CHANGENUM;
- error = DoIO(diskreq);
- ChangeCount[x] = diskreq->io_Actual; /* save changecount for later */
- CloseDevice(diskreq);
- };
-
- }
-
- /********************************/
- /* This routine returns which drive changed disks lately */
- /********************************/
- WhoChanged()
- {
- int RetVal; /* The value we'll return */
-
- RetVal = -1; /* return -1 if all else fails */
- for (x = 0; x < 4; x++)
- {
- if (ChangeCount[x] == 0) continue; /* no drive here */
- error = OpenDevice("trackdisk.device",x,diskreq,0);
- if (error > 0) continue; /* no drive here */
-
- diskreq->io_Command = TD_CHANGESTATE;
- DoIO(diskreq);
- if (diskreq->io_Actual != 0)
- {
- continue;
- };
-
- diskreq->io_Command = TD_CHANGENUM;
- DoIO(diskreq);
- if (diskreq->io_Actual != ChangeCount[x])
- {
- RetVal = x;
- ChangeCount[x] = diskreq->io_Actual;
- CloseDevice(diskreq);
- goto Out;
- };
- CloseDevice(diskreq);
- };
- Out:;
- return(RetVal);
- }
- /********************************/
-
- CheckBlock()
- {
- int Sum, Bootable, Virus; /* Virus is a flag, Bootable is a flag, Sum the cksum. */
- int BBandit; /* BBandit is a flag too. Oh well. */
- int a, Unit;
- int SCA; /* don't get scared, it's just a flag. */
-
- while ((Unit = WhoChanged()) != -1)
- {
- DisksChecked++;
-
- SCA = FALSE;
- BBandit = FALSE;
-
- /* Unit # to open is returned by "WhoChanged()" up above. */
- if (Unit == -1) return;
- error = OpenDevice("trackdisk.device",Unit,diskreq,0);
- if (error > 0) return;
-
- /* I've heard stories that pulling a read request to block zero with a
- length of 1024 will cause the virus to write itself back. Not taking
- any chances. */
-
- diskreq->io_Command = CMD_READ;
- diskreq->io_Data = diskbuffer;
- diskreq->io_Length = 3*512;
- diskreq->io_Offset = 0;
- DoIO(diskreq);
-
- diskreq->io_Length = 0;
- diskreq->io_Command = TD_MOTOR;
- DoIO(diskreq); /* turn off motor */
-
- if (diskreq->io_Error > 19) return; /* disk error, lemme out */
- CloseDevice(diskreq);
-
- Sum = 0;
- for (a=0; a<1024; a=a+4)
- {
- LastSum = Sum;
- Sum = Sum + diskbuffer[a+3];
- Sum = Sum + (diskbuffer[a+2] * 256);
- Sum = Sum + (diskbuffer[a+1] * 65536);
- Sum = Sum + (diskbuffer[a] * (65536 * 256));
- if (LastSum > Sum) Sum++; /* took me a while to figger this out */
- }
-
- if (Sum != 0) return; /* if it's not bootable, we DONT want it! */
-
- if (diskbuffer[0x2b] == '9')
- if (diskbuffer[0x2c] == '.')
- if (diskbuffer[0x2d] == '8')
- if (diskbuffer[0x2e] == '7')
- {
- SCAFound++;
- BBandit = TRUE; /* 9.87 is part of BBandit Virus */
- };
-
- /* check specifically for SCA virus */
- if (diskbuffer[8] == 'C')
- if (diskbuffer[9] == 'H')
- if (diskbuffer[10] == 'W')
- {
- SCA = TRUE; /* CHW is part of SCA virus */
- SCAFound++;
- };
-
- /* compare boot block with real boot block. If it's not, notify God. */
- Virus = FALSE;
- for (x = 0; x < 39; x++) /* nuum of lements in bootblock */
- {
- if (diskbuffer[8+x] != bootblock[8+x])
- {
- Virus = TRUE;
- };
- };
-
- /* Oh no, a Virus! */
- if (Virus == TRUE)
- {
- NBCTEXT[23] = '0'+Unit; /* change DF9: to real drive in text */
- TEXTPTR[23] = '0'+Unit;
-
- if (SCA == TRUE)
- {
- /* OH NOOOOO, an SCA virus. Wimpo virus, compared to BBandit */
- Delay(1);
- error = AutoRequest(LittleWindow, &SCABody, &SCAPos, &SCANeg, 0, 0, 320, 70);
- if (error == TRUE) DoInstall(Unit); /* user wants it fixed. */
- Delay(1);
- }
- else if (BBandit == TRUE)
- {
- /* The Byte Bandit Virus. Tricky bugger, he WAS. */
- Delay(1);
- sprintf(CopyText, "(Copy Count on this disk: %d)", (diskbuffer[74]*256)+diskbuffer[75]);
- error = AutoRequest(LittleWindow, &BBDiskbody, &SCAPos, &SCANeg, 0, 0, 380, 80);
- if (error == TRUE) DoInstall(Unit); /* User crying for aid */
- Delay(1);
- }
- else
- {
- /* Probably just a custom boot block (or a new virus...) */
- Delay(1);
- error = AutoRequest(LittleWindow, &Body1, &Pos, &Neg, 0, 0, 320, 70);
- if (error == TRUE) DoInstall(Unit); /* user wants it neutered. */
- Delay(1);
- }
- };
-
-
- }; /* End of While Whochanged */
-
- }
-
- /********************************/
- /* This is where the boot code gets changed */
- /********************************/
- DoInstall(un)
- int un; /* unit to write to */
- {
- register int x;
- register int Sum;
- int err, a;
-
- /* Rewrite disk? Really? */
- error = AutoRequest(LittleWindow, &REWBody, &REWPos, &REWNeg, 0, 0, 320, 75);
- if (error != TRUE) return; /* user changed his brain. */
-
- DisksInstalled++;
-
- error = OpenDevice("trackdisk.device", un,diskreq,0);
- if (error > 0) return;
-
- trygain:
-
- diskreq->io_Command = TD_PROTSTATUS;
- DoIO(diskreq); /* check if disk is write protected */
-
- if (diskreq->io_Actual != 0)
- {
- error = AutoRequest(LittleWindow, &ERRBody, &ERRPos, &ERRNeg, 0, 0, 280, 75);
- if (error == TRUE) /* error is true or false, depending on user */
- {
- goto trygain;
- };
- CloseDevice(diskreq);
- return; /* unrecoverable write protect error!!!!!!!!! */
- };
-
-
- diskreq->io_Command = CMD_READ;
- diskreq->io_Data = diskbuffer; /* Move the drive head, make some noise so */
- diskreq->io_Length = 512; /* folks know we're doing something. */
- diskreq->io_Offset = 44*512;
- DoIO(diskreq);
-
- for (x = 0; x < 1024; x++)
- diskbuffer[x] = 0; /* clear diskbuffer to zero. clean. */
-
- for (x = 0; x < 50; x++)
- {
- diskbuffer[x] = bootblock[x]; /* copy boot code into buffer */
- };
-
- /* Write it ! */
-
-
- diskreq->io_Length = 1024; /* here we go! */
- diskreq->io_Data = &diskbuffer[0];
- diskreq->io_Command = CMD_WRITE;
- diskreq->io_Offset = 0L;
- DoIO(diskreq);
-
- diskreq->io_Command = CMD_UPDATE; /* flush buffer to disk */
- DoIO(diskreq);
-
- error = diskreq->io_Error;
-
- Delay(5);
- diskreq->io_Length = 0;
- diskreq->io_Command = ETD_MOTOR;
- DoIO(diskreq); /* turn off motor */
-
- CloseDevice(diskreq);
-
- if (error > 19)
- {
- SetWindowTitles(LittleWindow, "Error, Nothing Done.", -1);
- }
- else
- {
- SetWindowTitles(LittleWindow, "Disk Healed.", -1);
- };
-
- Delay(100);
- SetWindowTitles(LittleWindow, TITLETEXT, -1);
-
- }
- /************************/
-
-
- CheckMemoryForViruses()
- {
- int VirusBase; /* ick, whatta name! */
- int Temp;
- struct ExecBase *ExecBase;
- int *LongMemPointer; /* Used for reading FROM memory */
-
- ExecBase = OpenLibrary("exec.library", 0);
-
- LongMemPointer = FindName(&ExecBase->DeviceList, "trackdisk.device");
-
- Temp = LongMemPointer;
- Temp = Temp - 0x1c;
- LongMemPointer = Temp; /* Can't do LongMemPointer - 0x1c because then it's
- a pointer operation and we get a wrong value */
- VirusBase = (*LongMemPointer) - 0x1b8;
-
- LongMemPointer = VirusBase;
-
- if (*LongMemPointer == ('D'<<24) + ('O'<<16) + ('S'<<8)) /* klugo */
- {
-
- /* Ok, so we don't really remove it from memory, but we DO render
- it harmless. */
-
- PatchMem(VirusBase+0xaa, 0x4e71);
- PatchMem(VirusBase+0xac, 0x4e71);
- PatchMem(VirusBase+0xae, 0x4e71);
- PatchMem(VirusBase+0xb0, 0x4e71); /* NOP's */
- PatchMem(VirusBase+0x1c2, 0x6000); /* Change Bxx to BRA */
- PatchMem(VirusBase+0x2d2, 0x6000); /* Disable TD and VTI code */
- PatchMem(VirusBase+0x388, 0x4e75); /* Make sure it doesn't come back */
- PatchMem(VirusBase+0x3ea, 0x0000); /* Kill resident matchword */
- PatchMem(VirusBase, 0x0000); /* so WE don't find it again */
- error = AutoRequest(LittleWindow, &BBMem1, &BBMPos, &BBMNeg, 0, 0, 395, 78);
- };
-
-
- CloseLibrary(ExecBase);
- }
-
- /***********************/
-
- /**********************/
- PatchMem(loc, val)
- short *loc;
- int val;
- {
- *loc = val;
- }
-